<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>

<script>
    // 1 语句
    // 语句（statement）是为了完成某种任务而进行的操作，比如下面就是一行赋值语句。
    var a = 1 + 3;
    console.log(a)

    // 语句以分号结尾，一个分号就表示一个语句结束。多个语句可以写在一行内。
    var a = 1 + 3; var b = 'abc';
    console.log(a, b)

    // 表达式不需要分号结尾。一旦在表达式后面添加分号，则 JavaScript 引擎就将表达式视为语句，这样会产生一些没有任何意义的语句。
    1 + 3;
    'abc';

    console.log("******************************************************************************************************")

    // 2 变量

    // 概念 
    // 变量是对“值”的具名引用。变量就是为“值”起名，然后引用这个名字，就等同于引用这个值。变量的名字就是变量名。
    var a;
    a = 1;
    console.log(a)

    // 如果只是声明变量而没有赋值，则该变量的值是undefined。undefined是一个特殊的值，表示“无定义”。
    var a;
    a // undefined
    console.log(a)

    //变量提升
    // JavaScript 引擎的工作方式是，先解析代码，获取所有被声明的变量，然后再一行一行地运行。这造成的结果，就是所有的变量的声明语句，都会被提升到代码的头部，这就叫做变量提升（hoisting）。
    console.log(a);
    var a = 1;

    var a;
    console.log(a);
    a = 1;

    console.log("******************************************************************************************************")

    // 3 标识符
    // 标识符（identifier）指的是用来识别各种值的合法名称。最常见的标识符就是变量名，以及后面要提到的函数名。JavaScript 语言的标识符对大小写敏感，所以a和A是两个不同的标识符。

    // 标识符命名规则如下。
    // 第一个字符，可以是任意 Unicode 字母（包括英文字母和其他语言的字母），以及美元符号（$）和下划线（_）。
    // 第二个字符及后面的字符，除了 Unicode 字母、美元符号和下划线，还可以用数字0-9。

    // // 下面这些都是合法的标识符。
    //     arg0
    //     _tmp
    //     $elem
    //     π
    // // 下面这些则是不合法的标识符。
    //     1a  // 第一个字符不能是数字
    //     23  // 同上
    //     ***  // 标识符不能包含星号
    //     a + b  // 标识符不能包含加号
    //     - d  // 标识符不能包含减号或连词线

    //中文是合法的标识符，可以用作变量名。
    // var 临时变量 = 1;

    //JavaScript 有一些保留字，不能用作标识符：
    // arguments、break、case、catch、class、const、continue、debugger、default、delete、do、else、
    // enum、eval、export、extends、false、finally、for、function、if、implements、import、in、instanceof、interface、let、new、null、
    // package、private、protected、public、return、static、super、switch、this、throw、true、try、typeof、var、void、while、with、yield。

    console.log("******************************************************************************************************")

    // 4 注释
    // 源码中被 JavaScript 引擎忽略的部分就叫做注释，它的作用是对代码进行解释。JavaScript 提供两种注释的写法：一种是单行注释，用//起头；另一种是多行注释，放在/*和*/之间。
    // 这是单行注释
    /*
     这是
     多行
     注释
    */

    // 上面代码中，只有x = 1会执行，其他的部分都被注释掉了。需要注意的是，-->只有在行首，才会被当成单行注释，否则会当作正常的运算。
    // x = 1; < !--x = 2;
    // --> x = 3;

    function countdown(n) {
        // 上面代码中，n --> 0实际上会当作n-- > 0，因此输出2、1、0。
        while (n-- > 0) console.log(n);
    }
    countdown(3)

    console.log("******************************************************************************************************")

    // 5 区块
    {
        var a = 1;
    }
    a // 1


    // 6 条件语句
    // if 结构
    // if…else 结构
    // if…else 结构
    // switch 结构
    // 三元运算符 ?:

    // 7 循环语句
    // while 循环
    //  for 循环
    // do…while 循环
    //  break 语句和 continue 语句

    // 标签（label）
    // JavaScript 语言允许，语句的前面有标签（label），相当于定位符，用于跳转到程序的任意位置，标签的格式如下。

    // 标签通常与break语句和continue语句配合使用，跳出特定的循环。
    top:
    for (var i = 0; i < 3; i++) {
        for (var j = 0; j < 3; j++) {
            if (i === 1 && j === 1) break top;
            console.log('i=' + i + ', j=' + j);
        }
    }
    // i=0, j=0
    // i=0, j=1
    // i=0, j=2
    // i=1, j=0
    // 上面代码为一个双重循环区块，break命令后面加上了top标签（注意，top不用加引号），满足条件时，直接跳出双层循环。如果break语句后面不使用标签，则只能跳出内层循环，进入下一次的外层循环。

    // 标签也可以用于跳出代码块。
    foo: {
        console.log(1);
        break foo;
        console.log('本行不会输出');
    }
    console.log(2);
    // 1
    // 2
    // 上面代码执行到break foo，就会跳出区块。

    // continue语句也可以与标签配合使用。
    top:
    for (var i = 0; i < 3; i++) {
        for (var j = 0; j < 3; j++) {
            if (i === 1 && j === 1) continue top;
            console.log('i=' + i + ', j=' + j);
        }
    }
    // i=0, j=0
    // i=0, j=1
    // i=0, j=2
    // i=1, j=0
    // i=2, j=0
    // i=2, j=1
    // i=2, j=2
    // 上面代码中，continue命令后面有一个标签名，满足条件时，会跳过当前循环，直接进入下一轮外层循环。如果continue语句后面不使用标签，则只能进入下一轮的内层循环。

    // 参考链接
    // Axel Rauschmayer, A quick overview of JavaScript

</script>

</html>